package streams

import "gitee.com/hongzhaomin/hzm-common-go/assert"

// MapK 类型约束
//type MapK interface {
//	int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 |
//		float32 | float64 | string | bool | complex64 | complex128
//}

// ToMapIdentity 将集合ts转换为map[K]T, 根据getKey函数指定 “K类型” 的key
func ToMapIdentity[T any, K comparable](ts []T, getKey func(t T) K) map[K]T {
	assert.NonNil(getKey, "getKey func must not nil")
	newMap := make(map[K]T, len(ts))
	for _, t := range ts {
		key := getKey(t)
		newMap[key] = t
	}
	return newMap
}

// ToMap 将集合ts转换为map[K]V, 根据getKey函数指定 “K类型” 的key，根据getVal函数指定 “V类型” 的value
func ToMap[T any, K comparable, V any](ts []T, getKey func(t T) K, getVal func(t T) V) map[K]V {
	assert.NonNil(getKey, "getKey func must not nil")
	assert.NonNil(getVal, "getVal func must not nil")
	newMap := make(map[K]V, len(ts))
	for _, t := range ts {
		key := getKey(t)
		val := getVal(t)
		newMap[key] = val
	}
	return newMap
}

// GroupingByIdentity 将集合ts根据key分组转换为map[K][]T, 根据getKey函数指定 “K类型” 的key
func GroupingByIdentity[T any, K comparable](ts []T, getKey func(t T) K) map[K][]T {
	assert.NonNil(getKey, "getKey func must not nil")
	newMap := make(map[K][]T, len(ts)/2)
	for _, t := range ts {
		k := getKey(t)
		if vs, ok := newMap[k]; ok {
			newMap[k] = append(vs, t)
		} else {
			newMap[k] = []T{t}
		}
	}
	return newMap
}

// GroupingBy 将集合ts根据key分组转换为map[K][]V, 根据getKey函数指定 “K类型” 的key，根据getVal函数指定 “V类型” 的value
func GroupingBy[T any, K comparable, V any](ts []T, getKey func(t T) K, getVal func(t T) V) map[K][]V {
	assert.NonNil(getKey, "getKey func must not nil")
	assert.NonNil(getVal, "getVal func must not nil")
	newMap := make(map[K][]V, len(ts)/2)
	for _, t := range ts {
		k := getKey(t)
		v := getVal(t)
		if vs, ok := newMap[k]; ok {
			newMap[k] = append(vs, v)
		} else {
			newMap[k] = []V{v}
		}
	}
	return newMap
}
